import React from "react";
import VoiceRecorder from "./VoiceRecorder";
import StreamAudioPlayer from "./StreamAudioPlayer";
import { message } from "antd";
import { isString } from "lodash";

type State = {
  stage: "init" | "voice" | "speek";
};

type Props = unknown;

export default class ChatVoiceView extends React.Component<Props, State> {
  private audioPlayer: StreamAudioPlayer;

  constructor(props: Props) {
    super(props);
    this.state = { stage: "init" };
    this.audioPlayer = new StreamAudioPlayer(); // TODO: 什么时候关闭
    this.audioPlayer.play();
  }

  handleSendAndReceive = (blob: Blob) => {
    this.setState({ stage: "speek" });
    const socket = new WebSocket(`ws://${location.host}/ws/chat`);
    socket.onopen = (e) => {
      console.log("ws open", e);
      socket.send(blob);
    };
    socket.onclose = (e) => {
      this.setState({ stage: "init" });
      console.log("ws closed", e);
    };
    socket.onerror = (e) => {
      this.setState({ stage: "init" });
      message.error("对话出错");
      console.error("ws error", e);
    };
    socket.onmessage = async (e) => {
      if (e.data instanceof ArrayBuffer) {
        this.audioPlayer.addAudioChunk(e.data);
      } else if (e.data instanceof Blob) {
        this.audioPlayer.addAudioChunk(await e.data.arrayBuffer());
      } else if (isString(e.data)) {
        console.log("audio text:", e.data);
      }
    };
  };

  handleVoiceRecord = (blob: Blob) => {
    this.handleSendAndReceive(blob);
  };

  handleVoiceStart = () => {
    this.setState({ stage: "voice" });
  };

  render() {
    const { stage } = this.state;
    return (
      <div className="flex justify-center p-8">
        <VoiceRecorder
          stage={stage}
          onFinish={this.handleVoiceRecord}
          onStart={this.handleVoiceStart}
        />
      </div>
    );
  }
}
